import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.file.Files;
import java.util.UUID;

public class TcpServer3 {
    // 服务器端要绑定的固定端口号
    private static final int PORT = 8888;
    // 本地文件目录要展示的根路径
    private static final String BASE_PATH = "D:\\";

    public static void main(String[] args) throws IOException {
        // 1. 创建一个服务端 ServerSocket， 用于收发TCP报文
        ServerSocket server = new ServerSocket(PORT);
        while(true){
            // 2. 等待客户端连接， 该方法为阻塞方法
            Socket socket = server.accept();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try{
                        System.out.println("客户端建立TCP连接...");
                        System.out.printf("客户端IP：%s%n",socket.getInetAddress().getAddress());
                        System.out.printf("客户端端口号：%s%n",socket.getPort());
                        // 5. 接收客户端的数据， 需要从客户端Socket中的输入流获取
                        InputStream is = socket.getInputStream();
                        // 解析为请求对象
                        Request request = Request.serverParse(is);
                        System.out.println("服务端收到请求："+request);

                        // 6.根据请求处理业务：处理完返回响应对象
                        Response response = build(request);

                        // 7. 返回响应给客户端：通过客户端socket中的输出流发送响应数据
                        OutputStream os = socket.getOutputStream();
                        //7-1 返回响应的内容：按照约定格式输出响应对象中的内容
                        System.out.println("服务端返回响应："+response);
                        response.serverWrite(os);

                        // 7-3 双方关闭连接：服务端是关闭客户端socket 连接
                        socket.close();
                        System.out.println("————————————————————————————————————————————");

                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }).start();
        }
    }

    // 根据请求处理业务， 返回响应对象
    public static Response build(Request request) throws IOException {
        Response response = new Response();
        response.setStatus(200);
        File url = new File(BASE_PATH+request.getUrl());
        // 该路径的文件或目录不存在
        if(!url.exists()){
            response.setStatus(404);
            response.setData("");
            return response;
        }
        try{
            switch(request.getType()){
                // 1. 展示目录 文件列表
                case 1:{
                    File[] children = url.listFiles();
                    if(children == null){
                        response.setData("");
                    }else {
                        // 拼接要返回的数据： 文件列表
                        StringBuilder sb = new StringBuilder();
                        for (int i = 0; i < children.length; i++) {
                            File child = children[i];
                            // 文件路径截取掉 服务端本地路径前缀
                            sb.append(child.getAbsolutePath().substring(BASE_PATH.length())+"\n");
                        }
                        response.setData(sb.toString());
                    }
                    break;
                }
                // 2.文件重命名
                case 2:{
                    url.renameTo(new File(url.getParent()+File.separator+ request.getData()));
                    break;
                }
                // 3. 删除文件
                case 3:{
                    url.delete();
                    break;
                }
                // 4. 上传文件
                case 4:{
                    // 上传到请求的操作路径目录下， 保存的文件名 随机生成
                    try {
                        FileWriter upload = new FileWriter(url.getAbsolutePath()+File.separator+ UUID.randomUUID());
                        upload.write(request.getData());
                        System.out.println(request.getData());
                        upload.flush();
                        upload.close();
                        break;
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
                // 下载文件
                case 5:{
                    String data = new String(Files.readAllBytes(url.toPath()));
                    response.setData(data);
                    break;
                }
            }

        }catch (IOException e){
            e.printStackTrace();
        }
        return response;
    }


}
